package com.party.jackclientandroid.controller;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.provider.Settings;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.party.jackclientandroid.BaseActivity;
import com.party.jackclientandroid.R;
import com.party.jackclientandroid.MApplication;
import com.party.jackclientandroid.event.AMapBeanEvent;
import com.party.jackclientandroid.permission.RuntimeRationale;
import com.party.jackclientandroid.utils.ConstUtils;
import com.party.jackclientandroid.utils.MLogUtils;
import com.party.jackclientandroid.utils.MapUtil;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.Permission;
import com.yanzhenjie.permission.Setting;
import com.zyyoona7.popup.EasyPopup;

import java.lang.ref.WeakReference;
import java.util.List;

public class AMapController {
    private static final String TAG = AMapController.class.getSimpleName();
    private AMapLocationClient locationClient = null;
    private AMapLocationClientOption locationOption = new AMapLocationClientOption();
    private WeakReference<BaseActivity> mActivity;
    private AlertDialog mAlertDialog;
    private EasyPopup navigationPopup;
    private double currLongitude, currLatitude;
    private ViewGroup wholeLayout;
    private View helpView;
    public static int ACTION_LOCATION_SOURCE_SETTINGS = 100;

    /**
     * 定位监听
     */
    AMapLocationListener locationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation loc) {
            if (null != loc) {
                // 当前位置是否发生了改变
                String[] permissions = new String[]{Permission.ACCESS_COARSE_LOCATION, Permission.ACCESS_FINE_LOCATION};
                if (loc.getErrorCode() == 0) {
                    // 获取到位置之后把弹窗消失掉
                    if (mAlertDialog != null) mAlertDialog.dismiss();

                    AMapBeanEvent aMapBeanEvent = new AMapBeanEvent();
                    aMapBeanEvent.setErrorCode(loc.getErrorCode());
                    aMapBeanEvent.setLongitude(loc.getLongitude());
                    aMapBeanEvent.setLatitude(loc.getLatitude());
                    aMapBeanEvent.setProvince(loc.getProvince());
                    aMapBeanEvent.setAdCode(loc.getAdCode());
                    aMapBeanEvent.setCity(loc.getCity());
                    aMapBeanEvent.setDistrict(loc.getDistrict());
                    aMapBeanEvent.setCounty(loc.getCountry());
                    aMapBeanEvent.setCityCode(loc.getCityCode());
                    aMapBeanEvent.setAddress(loc.getAddress());
                    aMapBeanEvent.setRoad(loc.getRoad());
                    aMapBeanEvent.setStreet(loc.getStreet());
                    // 保存一份数据到全局变量里面
                    ((MApplication) mActivity.get().getApplication()).setMap(aMapBeanEvent);
                    // 发送定位事件给需要的界面使用
                    if (mActivity.get() != null && mActivity.get().getApplication() instanceof MApplication) {
                        mActivity.get().localComplete(aMapBeanEvent);
                    }
                    if (mLocationFinish != null) mLocationFinish.onClick(null);
                } else if (loc.getErrorCode() == 12) {
                    DialogController.showMustConfirmDialog(mActivity.get(), "需要获取地理位置\n便于为你提供准确的附近信息", (View v) -> {
                        Intent intent = new Intent();
                        intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        mActivity.get().startActivityForResult(intent, ACTION_LOCATION_SOURCE_SETTINGS);
                    });
                } else {
                    showSettingDialog(mActivity.get(), permissions);
                    MLogUtils.d(TAG, "定位失败" + " 错误码:" + loc.getErrorCode());
                }
            } else {
                MLogUtils.d(TAG, "定位失败，loc is null");
            }
            // 这里如果不调用停止,会一直定位
            if (!ConstUtils.LOCATION_ALWAYS) {
                destroyLocation();
            }
        }
    };

    public AMapController(Activity activity) {
        this.mActivity = new WeakReference<>((BaseActivity) activity);
    }

    /**
     * Display setting dialog.
     */
    public void showSettingDialog(Context context, final String[] permissions) {
        // 这里由于手机熄灭屏幕太久之后就会出现,之前获取到过数据就不再使用权限弹窗了
        if (mActivity.get().getApplication() instanceof MApplication) {
            AMapBeanEvent mapBeanEvent = ((MApplication) mActivity.get().getApplication()).getMap();
            if (mapBeanEvent != null) {
                return;
            }
        }
        List<String> permissionNames = Permission.transformText(context, permissions);
        String message = context.getString(R.string.message_permission_always_failed, TextUtils.join("\n", permissionNames));
        if (mAlertDialog == null) {
            mAlertDialog = new AlertDialog.Builder(mActivity.get())
                    .setCancelable(false)
                    .setTitle(R.string.title_dialog)
                    .setMessage(message)
                    .setPositiveButton(R.string.setting, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            setPermission(permissions);
                            mAlertDialog.dismiss();
                        }
                    })
                    .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            mAlertDialog.dismiss();
                        }
                    }).show();
        } else {
            if (!mAlertDialog.isShowing()) {
                mAlertDialog.show();
            }
        }
    }

    public void setPermission(final String[] permissions) {
        AndPermission.with(mActivity.get()).runtime().setting()
                .onComeback(new Setting.Action() {
                    @Override
                    public void onAction() {
                        if (AndPermission.hasPermissions(mActivity.get(), permissions)) {
                            startLocation2();
                        } else {
                            showSettingDialog(mActivity.get(), permissions);
                        }
                    }
                }).start();
    }

    /**
     * 开始定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private void startLocation2() {
        initLocation();
        // 设置定位参数
        locationClient.setLocationOption(locationOption);
        // 启动定位
        locationClient.startLocation();
    }

    /**
     * 销毁定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    public void destroyLocation() {
        try {
            ConstUtils.LOCATION_ALWAYS = false;
            if (null != locationClient) {
                /**
                 * 如果AMapLocationClient是在当前Activity实例化的，
                 * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
                 */
                stopLocation();
                locationClient.onDestroy();
                locationClient = null;
                locationOption = null;
            }
        } catch (Exception e) {

        }
    }

    /**
     * 默认的定位参数
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(false);//可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(30 * 1000);//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(60 * 1000);//可选，设置定位间隔。默认为2秒
        mOption.setNeedAddress(true);//可选，设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(false);//可选，设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(false);//可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(false);//可选，设置是否使用传感器。默认是false
        mOption.setWifiScan(true); //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.setLocationCacheEnable(true); //可选，设置是否使用缓存定位，默认为true
        mOption.setWifiActiveScan(false);   //设置是否强制刷新WIFI，默认为true，强制刷新
        mOption.setMockEnable(false);  // 设置是否允许模拟位置,默认为false，不允许模拟位置
        return mOption;
    }

    /**
     * 初始化定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private void initLocation() {
        //初始化client
        locationClient = new AMapLocationClient(mActivity.get().getApplicationContext());
        //设置定位参数
        locationClient.setLocationOption(getDefaultOption());
        // 设置定位监听
        locationClient.setLocationListener(locationListener);
    }

    public void startLocation() {
        final String[] permissions = new String[]{Permission.ACCESS_COARSE_LOCATION, Permission.ACCESS_FINE_LOCATION};
        AndPermission.with(mActivity.get())
                .runtime()
                .permission(permissions)
                .rationale(new RuntimeRationale())
                .onGranted(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> data) {
                        Log.e("checkPermissions", "获取权限成功");
                        checkLocationPermissionsAgain(true, permissions);
                    }
                })
                .onDenied(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> data) {
                        Log.e("checkPermissions", "获取权限失败");
                        checkLocationPermissionsAgain(false, permissions);
                    }
                }).start();
    }

    /**
     * 用户点击不在提示,或者在应用管理里面关闭权限之后
     */
    public void checkLocationPermissionsAgain(boolean onGranted, String[] permissions) {
        if (mActivity.get() == null) return;
        if (onGranted) {
            if (AndPermission.hasPermissions(mActivity.get(), permissions)) {
                startLocation2();
            } else {
                showSettingDialog(mActivity.get(), permissions);
            }
        } else {
            if (AndPermission.hasAlwaysDeniedPermission(mActivity.get(), permissions)) {
                showSettingDialog(mActivity.get(), permissions);
            }
        }
    }

    /**
     * 停止定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private void stopLocation() {
        // 停止定位
        locationClient.stopLocation();
    }

    public void showNavigationChoosePopupWindow() {
        if (navigationPopup == null) {
            View navigationChooseView = getNavigationView();
            navigationChooseView.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        if (navigationPopup != null) {
                            navigationPopup.dismiss();
                            navigationPopup = null;
                        }
                        return true;
                    }
                    return false;
                }
            });

            navigationPopup = EasyPopup.create(mActivity.get())
                    .setContentView(navigationChooseView)
                    .setAnimationStyle(R.style.Popupwindow)
                    .setBackgroundDimEnable(true)
                    .setDimValue(0.4f)
                    .setDimColor(Color.GRAY)
                    .setDimView(wholeLayout)
                    .setFocusAndOutsideEnable(true)
                    .setWidth(ViewGroup.LayoutParams.MATCH_PARENT)
                    .setHeight(ViewGroup.LayoutParams.WRAP_CONTENT)
                    .apply();
        }
        navigationPopup.showAtLocation(helpView, Gravity.BOTTOM, 0, 0);
    }

    public View getNavigationView() {
        View view = mActivity.get().getLayoutInflater().inflate(R.layout.popup_window_navigation_choose, null);
        TextView baidu_map_tv = (TextView) view.findViewById(R.id.baidu_map_tv);
        TextView gaode_map_tv = (TextView) view.findViewById(R.id.gaode_map_tv);
        TextView tengxun_map_tv = (TextView) view.findViewById(R.id.tengxun_map_tv);
        TextView cancel_tv = (TextView) view.findViewById(R.id.cancel_tv);
        baidu_map_tv.setOnClickListener(onClickListener);
        gaode_map_tv.setOnClickListener(onClickListener);
        tengxun_map_tv.setOnClickListener(onClickListener);
        cancel_tv.setOnClickListener(onClickListener);
        if (!MapUtil.isPackageInstalled("com.baidu.BaiduMap")) {
            baidu_map_tv.setVisibility(View.GONE);
        }
        if (!MapUtil.isPackageInstalled("com.autonavi.minimap")) {
            gaode_map_tv.setVisibility(View.GONE);
        }
        if (!MapUtil.isPackageInstalled("com.tencent.map")) {
            tengxun_map_tv.setVisibility(View.GONE);
        }
        return view;
    }

    private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.baidu_map_tv:
                    // 百度地图
                    Intent naviIntent = new Intent("android.intent.action.VIEW", android.net.Uri.parse("baidumap://map/geocoder?location=" + currLatitude + "," + currLongitude));
                    mActivity.get().startActivity(naviIntent);
                    if (navigationPopup != null && navigationPopup.isShowing()) {
                        navigationPopup.dismiss();
                    }
                    break;
                case R.id.gaode_map_tv:
                    // 高德地图
                    naviIntent = new Intent("android.intent.action.VIEW", android.net.Uri.parse("androidamap://route?sourceApplication=appName&slat=&slon=&sname=我的位置&dlat=" + currLatitude + "&dlon=" + currLongitude + "&dname=目的地&dev=0&t=2"));
                    mActivity.get().startActivity(naviIntent);
                    if (navigationPopup != null && navigationPopup.isShowing()) {
                        navigationPopup.dismiss();
                    }
                    break;
                case R.id.tengxun_map_tv:
                    // 腾讯地图
                    naviIntent = new Intent("android.intent.action.VIEW", android.net.Uri.parse("qqmap://map/routeplan?type=drive&from=&fromcoord=&to=目的地&tocoord=" + currLatitude + "," + currLongitude + "&policy=0&referer=appName"));
                    mActivity.get().startActivity(naviIntent);
                    if (navigationPopup != null && navigationPopup.isShowing()) {
                        navigationPopup.dismiss();
                    }
                    break;
                case R.id.cancel_tv:
                    if (navigationPopup != null && navigationPopup.isShowing()) {
                        navigationPopup.dismiss();
                    }
                    break;
            }
        }
    };

    public double getCurrLongitude() {
        return currLongitude;
    }

    public void setCurrLongitude(double currLongitude) {
        this.currLongitude = currLongitude;
    }

    public double getCurrLatitude() {
        return currLatitude;
    }

    public void setCurrLatitude(double currLatitude) {
        this.currLatitude = currLatitude;
    }

    public ViewGroup getWholeLayout() {
        return wholeLayout;
    }

    public void setWholeLayout(ViewGroup wholeLayout) {
        this.wholeLayout = wholeLayout;
    }

    public View getHelpView() {
        return helpView;
    }

    public void setHelpView(View helpView) {
        this.helpView = helpView;
    }


    View.OnClickListener mLocationFinish;

    public void setFinishListener(View.OnClickListener finishListener) {
        this.mLocationFinish = finishListener;
    }
}
